package com.example.ad.sdk.domain.repositories.interceptor;


import androidx.annotation.Nullable;

import com.alibaba.fastjson2.JSONObject;
import com.example.ad.sdk.domain.repositories.ParamsHelper;
import com.google.gson.Gson;
import com.google.gson.JsonIOException;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

/**
 * JsonConverterFactory 是一个用于将 JSON 数据与 Retrofit 请求/响应体进行转换的工厂类。
 * 它使用 Gson 库来处理 JSON 的序列化和反序列化。
 */
public class JsonConverterFactory extends Converter.Factory {
    private final Gson gson;

    /**
     * 创建一个默认的 JsonConverterFactory 实例，使用默认的 Gson 配置。
     *
     * @return JsonConverterFactory 实例
     */
    public static JsonConverterFactory create() {
        return create(new Gson());
    }

    /**
     * 创建一个 JsonConverterFactory 实例，使用指定的 Gson 配置。
     *
     * @param gson Gson 实例，用于 JSON 的序列化和反序列化
     * @return JsonConverterFactory 实例
     */
    public static JsonConverterFactory create(Gson gson) {
        return new JsonConverterFactory(gson);
    }

    /**
     * 私有构造函数，初始化 JsonConverterFactory 实例。
     *
     * @param gson Gson 实例，用于 JSON 的序列化和反序列化
     * @throws NullPointerException 如果 gson 为 null
     */
    private JsonConverterFactory(Gson gson) {
        if (gson == null) throw new NullPointerException("gson == null");
        this.gson = gson;
    }

    /**
     * 为 Retrofit 请求体提供 JSON 转换器。
     *
     * @param type 需要转换的 Java 类型
     * @param parameterAnnotations 方法参数的注解数组
     * @param methodAnnotations 方法的注解数组
     * @param retrofit Retrofit 实例
     * @return 用于将 Java 对象转换为 RequestBody 的 Converter 实例
     */
    @Nullable
    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new JsonRequestBodyConverter<>(gson, adapter);
    }

    /**
     * 为 Retrofit 响应体提供 JSON 转换器。
     *
     * @param type 需要转换的 Java 类型
     * @param annotations 方法的注解数组
     * @param retrofit Retrofit 实例
     * @return 用于将 ResponseBody 转换为 Java 对象的 Converter 实例
     */
    @Nullable
    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new JsonResponseBodyConverter<>(gson, adapter);
    }

    /**
     * JsonRequestBodyConverter 是一个将 Java 对象转换为 Retrofit 请求体的转换器。
     * 它使用 Gson 和 TypeAdapter 来处理 JSON 的序列化。
     *
     * @param <T> 需要转换的 Java 类型
     */
    private static class JsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
        private Gson gson;
        private TypeAdapter<T> adapter;

        /**
         * 构造函数，初始化 JsonRequestBodyConverter 实例。
         *
         * @param gson Gson 实例，用于 JSON 的序列化
         * @param adapter TypeAdapter 实例，用于处理特定类型的序列化
         */
        public JsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
            this.gson = gson;
            this.adapter = adapter;
        }

        /**
         * 将 Java 对象转换为 Retrofit 请求体。
         *
         * @param value 需要转换的 Java 对象
         * @return 包含 JSON 数据的 RequestBody 实例
         */
        @Override
        public RequestBody convert(T value) {

            JSONObject params = null;
            try {
                params = JSONObject.parseObject(value.toString());
            } catch (Exception ignored) {
            }
            params = ParamsHelper.getTo().apiCommonParams(params);
            return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), params.toJSONString());
        }
    }

    /**
     * JsonResponseBodyConverter 是一个将 Retrofit 响应体转换为 Java 对象的转换器。
     * 它使用 Gson 和 TypeAdapter 来处理 JSON 的反序列化。
     *
     * @param <T> 需要转换的 Java 类型
     */
    private static class JsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
        private final Gson gson;
        private final TypeAdapter<T> adapter;

        /**
         * 构造函数，初始化 JsonResponseBodyConverter 实例。
         *
         * @param gson Gson 实例，用于 JSON 的反序列化
         * @param adapter TypeAdapter 实例，用于处理特定类型的反序列化
         */
        JsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
            this.gson = gson;
            this.adapter = adapter;
        }

        /**
         * 将 Retrofit 响应体转换为 Java 对象。
         *
         * @param value 需要转换的 ResponseBody 实例
         * @return 转换后的 Java 对象
         * @throws IOException 如果读取或解析 JSON 数据时发生错误
         */
        @Override
        public T convert(ResponseBody value) throws IOException {
            JsonReader jsonReader = gson.newJsonReader(value.charStream());
            try {
                T result = adapter.read(jsonReader);
                if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
                    throw new JsonIOException("JSON document was not fully consumed.");
                }
                return result;
            } finally {
                value.close();
            }
        }
    }
}
